package cc.vv.baselibrary.util.http;

import android.support.annotation.NonNull;
import android.text.TextUtils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import cc.vv.baselibrary.util.router.RouterClassUtil;
import cc.vv.lkrouter.router.RouterActivity;

/**
 * 公共Object对象工具类
 * Created by sun.li on 2018/7/6.
 *
 * @author sun.li
 */

public class BaseObjectUtil {

    private static BaseObjectUtil mInstance;

    private BaseObjectUtil() {
    }

    public static BaseObjectUtil getInstance() {
        if(null == mInstance) {
            synchronized(RouterActivity.class) {
                if(null == mInstance) {
                    mInstance = new BaseObjectUtil();
                }
            }
        }
        return mInstance;
    }

    /** 调用Module中的对应无参方法*/
    public void callMethodInModule(@NonNull String className,@NonNull String methodName){
        Object object = RouterClassUtil.getInstance().getObject(className);
        if (null != object) {
            Method method = getMethod(object,methodName,null);
            if(null!=method){
                try {
                    //执行对象object中通过反射获取的方法
                    method.invoke(object);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /** 调用Module中的对应有参方法*/
    public void callMethodInModule(@NonNull String className, @NonNull String methodName, List<BaseObjectParameterBean> mList){
        if(null!=mList && mList.size()>0){
            /* 参数类型集合*/
            List<Class> classList = new ArrayList<>();
            /* 参数值集合*/
            List<Object> objectList = new ArrayList<>();
            for (int i = 0; i < mList.size(); i++) {
                BaseObjectParameterBean baseHttpRequestParameterBean = mList.get(i);
                if(null != baseHttpRequestParameterBean){
                    if(null != baseHttpRequestParameterBean.getParameterValue() && null != baseHttpRequestParameterBean.getParameterType()){
                        classList.add(baseHttpRequestParameterBean.getParameterType());
                        objectList.add(baseHttpRequestParameterBean.getParameterValue());
                    }
                }
            }
            if(classList.size()>0 && objectList.size()>0){
                Object object = RouterClassUtil.getInstance().getObject(className);
                if (null != object) {
                    Method method = getMethod(object,methodName,classList);
                    if(null!=method){
                        try {
                            //执行对象object中通过反射获取的方法
                            Object[] mObjectList = new Object[objectList.size()];
                            for (int i = 0; i < objectList.size(); i++) {
                                if(null != objectList.get(i)){
                                    mObjectList[i] = objectList.get(i);
                                }
                            }
                            method.invoke(object,mObjectList);
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        } catch (InvocationTargetException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }else{
            callMethodInModule(className,methodName);
        }
    }

    private Method getMethod(Object object, @NonNull String methodName, List<Class> mList){
        if(null == object || TextUtils.isEmpty(methodName)){
            return null;
        }
        Method method = null;
        try {

            if(null != mList && mList.size()>0){
                // 父类对象调用子类有参数的方法(反射原理)
                Class[] mClassList = new Class[mList.size()];
                for (int i = 0; i < mList.size(); i++) {
                    if(null != mList.get(i)){
                        mClassList[i] = mList.get(i);
                    }
                }
                method = object.getClass().getMethod(methodName,mClassList);
            }else{
                method = object.getClass().getMethod(methodName);// 父类对象调用子类方法(反射原理)
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return method;
    }

}
